package com.concurrent.demo;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Date 2020/7/9 16:44
 * @Author admin
 * @Description
 */
public class Cache<K, V> {
    final Map<K, V> m = new HashMap<>();
    final ReadWriteLock rwl = new ReentrantReadWriteLock();
    //读锁
    final Lock r = rwl.readLock();
    //写锁
    final Lock w = rwl.writeLock();

    //读缓存
    V get(K key) {
        V v = null;
        r.lock();
        //读锁不能升级为写锁，所以下面的是不对的，只能先释放读锁，再获取写锁，但是获取了写锁可以继续获取读锁，即锁的降级
//        try {
//            v = m.get(key);
//            if(v==null){
//                //查数据库
//                w.lock();
//                try {
//                    m.put(key,v);
//                }finally {
//                    w.unlock();
//                }
//            }
//            return m.get(key);
        try {
            v = m.get(key);
        } finally {
            r.unlock();
        }
        //缓存中存在
        if (v != null) {
            return v;
        }
        //查询数据库得到数据然后获取读锁存入缓存
        w.lock();
        try {
            //如果有其他上线查过数据库并且存到缓存了
            v = m.get(key);
            if (v == null) {
                //否则查询数据库拿到数据 放入缓存
                m.put(key, v);
            }
            return v;
        } finally {
            w.unlock();
        }
    }

    //写缓存
    void put(K key, V vlaue) {
        w.lock();
        try {
            m.put(key, vlaue);
        } finally {
            w.unlock();
        }
    }

    public static void main(String[] args) {
        Random random = new Random(3);
        Date date = new Date();
        System.out.println("date = " + date);
        long time = new Date().getTime();
        System.out.println("time = " + time);
        long l =  time-((new Random().nextInt(25))+5)*1000;
        System.out.println("l = " + l);
        System.out.println(new Date(l));
    }
}
